Add gtk_application_prefers_app_menu()
authorRyan Lortie <desrt@desrt.ca>
Mon, 30 Jun 2014 16:16:19 +0000 (12:16 -0400)
committerRyan Lortie <desrt@desrt.ca>
Thu, 3 Jul 2014 00:17:34 +0000 (20:17 -0400)
Applications can call this to determine if they should an app menu.
This will be %FALSE on desktop environments that do not have an
application menu like the one in gnome-shell.  It is %FALSE on Windows
and Mac OS.

Applications are completely free to totally ignore this API -- it is
only provided as a hint to help applications that may be interested in
supporting non-GNOME platforms with a more native 'look and feel'.

https://bugzilla.gnome.org/show_bug.cgi?id=722092

docs/reference/gtk/gtk3-sections.txt
gtk/gtkapplication-dbus.c
gtk/gtkapplication.c
gtk/gtkapplication.h
gtk/gtkapplicationimpl.c
gtk/gtkapplicationprivate.h

index 02a48afc09b568b404782b782b440a5c72c86ff6..d3e34c6dfabd507da08d8267a80bde2059fbe396 100644 (file)
@@ -7391,6 +7391,7 @@ gtk_application_uninhibit
 gtk_application_is_inhibited
 
 <SUBSECTION>
+gtk_application_prefers_app_menu
 gtk_application_get_app_menu
 gtk_application_set_app_menu
 gtk_application_get_menubar
index 09afcfa015b5082c229d1117f2139ff4d9021d0a..60d4edddf0321f4160369c1417ae6b8721cb7c52 100644 (file)
@@ -23,6 +23,7 @@
 #include "config.h"
 
 #include "gtkapplicationprivate.h"
+#include "gtksettings.h"
 
 G_DEFINE_TYPE (GtkApplicationImplDBus, gtk_application_impl_dbus, GTK_TYPE_APPLICATION_IMPL)
 
@@ -411,6 +412,38 @@ gtk_application_impl_dbus_is_inhibited (GtkApplicationImpl         *impl,
   return inhibited;
 }
 
+static gboolean
+gtk_application_impl_dbus_prefers_app_menu (GtkApplicationImpl *impl)
+{
+  static gboolean decided;
+  static gboolean result;
+
+  /* We do not support notifying if/when the result changes, so make
+   * sure that once we give an answer, we will always give the same one.
+   */
+  if (!decided)
+    {
+      GtkSettings *gtk_settings;
+      gboolean show_app_menu;
+      gboolean show_menubar;
+
+      gtk_settings = gtk_settings_get_default ();
+      g_object_get (G_OBJECT (gtk_settings),
+                    "gtk-shell-shows-app-menu", &show_app_menu,
+                    "gtk-shell-shows-menubar", &show_menubar,
+                    NULL);
+
+      /* We prefer traditional menus when we have a shell that doesn't
+       * show the appmenu or we have a shell that shows menubars
+       * (ie: Unity)
+       */
+      result = show_app_menu && !show_menubar;
+      decided = TRUE;
+    }
+
+  return result;
+}
+
 static void
 gtk_application_impl_dbus_init (GtkApplicationImplDBus *dbus)
 {
@@ -446,6 +479,7 @@ gtk_application_impl_dbus_class_init (GtkApplicationImplDBusClass *class)
   impl_class->inhibit = gtk_application_impl_dbus_inhibit;
   impl_class->uninhibit = gtk_application_impl_dbus_uninhibit;
   impl_class->is_inhibited = gtk_application_impl_dbus_is_inhibited;
+  impl_class->prefers_app_menu = gtk_application_impl_dbus_prefers_app_menu;
 
   gobject_class->finalize = gtk_application_impl_dbus_finalize;
 }
index a8b99811c2f95a18e49e3ee433f9113df19d7681..662e501e44fe25c635f915fee5b65a81faaf78f1 100644 (file)
@@ -1138,6 +1138,57 @@ gtk_application_remove_accelerator (GtkApplication *application,
   g_free (action_and_target);
 }
 
+/**
+ * gtk_application_prefers_app_menu:
+ * @application: a #GtkApplication
+ *
+ * Determines if the desktop environment in which the application is
+ * running would prefer an application menu be shown.
+ *
+ * If this function returns %TRUE then the application should call
+ * gtk_application_set_app_menu() with the contents of an application
+ * menu, which will be shown by the desktop environment.  If it returns
+ * %FALSE then you should consider using an alternate approach, such as
+ * a menubar.
+ *
+ * The value returned by this function is purely advisory and you are
+ * free to ignore it.  If you call gtk_application_set_app_menu() even
+ * if the desktop environment doesn't support app menus, then a fallback
+ * will be provided.
+ *
+ * Applications are similarly free not to set an app menu even if the
+ * desktop environment wants to show one.  In that case, a fallback will
+ * also be created by the desktop environment (GNOME, for example, uses
+ * a menu with only a "Quit" item in it).
+ *
+ * The value returned by this function never changes.  Once it returns a
+ * particular value, it is guaranteed to always return the same value.
+ *
+ * You may only call this function after the application has been
+ * registered and after the base startup handler has run.  You're most
+ * likely to want to use this from your own startup handler.  It may
+ * also make sense to consult this function while constructing UI (in
+ * activate, open or an action activation handler) in order to determine
+ * if you should show a gear menu or not.
+ *
+ * This function will return %FALSE on Mac OS and a default app menu
+ * will be created automatically with the "usual" contents of that menu
+ * typical to most Mac OS applications.  If you call
+ * gtk_application_set_app_menu() anyway, then this menu will be
+ * replaced with your own.
+ *
+ * Returns: %TRUE if you should set an app menu
+ *
+ * Since: 3.14
+ **/
+gboolean
+gtk_application_prefers_app_menu (GtkApplication *application)
+{
+  g_return_val_if_fail (application->priv->impl != NULL, FALSE);
+
+  return gtk_application_impl_prefers_app_menu (application->priv->impl);
+}
+
 /**
  * gtk_application_set_app_menu:
  * @application: a #GtkApplication
index 7ff13ad44b458ebe3b721525b2dd06d818e4cd2f..9d1af95e10a5ed6e6c29a3b65bc22676b6c00e82 100644 (file)
@@ -151,6 +151,9 @@ void             gtk_application_set_accels_for_action           (GtkApplication
                                                                   const gchar          *detailed_action_name,
                                                                   const gchar * const  *accels);
 
+GDK_AVAILABLE_IN_3_14
+gboolean         gtk_application_prefers_app_menu                (GtkApplication       *application);
+
 G_END_DECLS
 
 #endif /* __GTK_APPLICATION_H__ */
index 6cb899aad34e693e37213ab6f1fd56fd959705e3..946284b19a44a62f9d2c626bb2456bccedadeea9 100644 (file)
@@ -41,6 +41,7 @@ gtk_application_impl_init (GtkApplicationImpl *impl)
 }
 
 static guint do_nothing (void) { return 0; }
+static gboolean return_false (void) { return FALSE; }
 
 static void
 gtk_application_impl_class_init (GtkApplicationImplClass *class)
@@ -59,6 +60,7 @@ gtk_application_impl_class_init (GtkApplicationImplClass *class)
   class->inhibit = (gpointer) do_nothing;
   class->uninhibit = (gpointer) do_nothing;
   class->is_inhibited = (gpointer) do_nothing;
+  class->prefers_app_menu = (gpointer) return_false;
 }
 
 void
@@ -153,6 +155,12 @@ gtk_application_impl_is_inhibited (GtkApplicationImpl         *impl,
   return GTK_APPLICATION_IMPL_GET_CLASS (impl)->is_inhibited (impl, flags);
 }
 
+gboolean
+gtk_application_impl_prefers_app_menu (GtkApplicationImpl *impl)
+{
+  return GTK_APPLICATION_IMPL_GET_CLASS (impl)->prefers_app_menu (impl);
+}
+
 GtkApplicationImpl *
 gtk_application_impl_new (GtkApplication *application,
                           GdkDisplay     *display)
index 5378c23b17c3003206c1c7faed058d4bae8c5ab6..dbd711563b1ee976bfecbab9d939ce6241fe6a9a 100644 (file)
@@ -103,6 +103,8 @@ typedef struct
   gboolean    (* is_inhibited)              (GtkApplicationImpl          *impl,
                                              GtkApplicationInhibitFlags   flags);
 
+  gboolean    (* prefers_app_menu)          (GtkApplicationImpl          *impl);
+
 
 } GtkApplicationImplClass;
 
@@ -184,6 +186,8 @@ gboolean                gtk_application_impl_is_inhibited               (GtkAppl
 
 gchar *                 gtk_application_impl_dbus_get_window_path       (GtkApplicationImplDBus      *dbus,
                                                                          GtkWindow                   *window);
+gboolean                gtk_application_impl_prefers_app_menu           (GtkApplicationImpl          *impl);
+
 
 void                    gtk_application_impl_quartz_setup_menu          (GMenuModel                  *model,
                                                                          GtkActionMuxer              *muxer);